// 1. 引入 koa
const Koa = require('koa')
const { koaBody } = require('koa-body')
// 导入 CORS 中间件
const koaCors = require('@koa/cors')
// 导入错误处理中间件
const koaError = require('koa-json-error')
// 导入校验参数中间件
const koaParameter = require('koa-parameter')
// 导入session中间件
const koaSession = require('koa-session')
// 导入路由器实例
const router = require('./router')

// 2. 创建 koa 实例
const app = new Koa()
// 中间件:session
app.keys = ['some secret hurr'];  //cookie的签名
app.use(koaSession({
    key: 'koa.sess',
    maxAge: 50000,  // 需要修改
    overwrite: true,  // 默认
    httpOnly: true,  // true表示只有服务器端可以获取
    signed: true,   // 签名
    rolling: false, // 每次请求时强行设置cookie，这将重置cookie过期时间
    renew: true, // 需要修改true
}, app));
// 中间件：CORS 跨域
app.use(koaCors())
// 中间件：统一错误处理和错误信息输出
app.use(koaError({
    // 自定义出错时，接口返回数据的格式
    format: (err, obj) => {
        console.log(obj);
        if (obj.code === 'INVALID_PARAM') {
            // 企业开发中基于安全考虑，对于参数校验错误，后端无需告知前端更多错误细节
            // （即只需告诉前端参数不合法即可）
            return {
                code: 40022,
                message: '存在不合法参数!'
            }
        } else if (obj.response.statusText === 'Too Many Requests') {
            return {
                code: 40011,
                message: '请求次数过多,请稍后再试'
            }
        }
        return {
            code: obj.code || 50000,
            message: obj.message || err.message
        }
    }
}))
// 中间件：请求参数校验
// 使用 app.use 则会添加 koa-parameter 自己的错误处理中间件,就不会走我们的 koa-error 了,所以这里不需要app.use
// app.use(koaParameter(app))
koaParameter(app)
// 中间件：请求体参数获取
app.use(koaBody({
    // 支持文件上传
    multipart: true,
    // 文件上传配置
    formidable: {
        // 上传文件保存目录
        uploadDir: './static/uploads',
        // 保留上传文件原来的后缀名
        keepExtensions: true
    }
}))

// 中间件：路由相关
app.use(router.routes())
app.use(router.allowedMethods())

// 4. 启动 koa 实例所关联的 http 服务器，并监听在 3000 端口上向外提供服务
app.listen(3000, () => {
    // http 服务器启动成功后执行本回调函数
    console.log('请访问 http://localhost:3000')
})